package org.openmore.opc.controller.api;

import io.swagger.annotations.*;
import org.openmore.common.exception.OpenmoreException;
import org.openmore.opc.annotation.TokenAuthCheck;
import org.openmore.opc.controller.BaseController;
import org.openmore.opc.dto.AppThirdLoginDto;
import org.openmore.opc.dto.BaseResponse;
import org.openmore.opc.dto.LoginParams;
import org.openmore.opc.dto.UserProfileDto;
import org.openmore.opc.entity.User;
import org.openmore.opc.entity.enums.LoginType;
import org.openmore.opc.framework.MyThreadLocalConfig;
import org.openmore.opc.service.AccountService;
import org.openmore.opc.service.LoginService;
import org.openmore.opc.service.UserService;
import org.openmore.opc.service.WechatMiniService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;

/**
 * THIS IS AUTO GENERATED SOURCE CODE
 * Created by org.openmore
 * on 2018-08-11
 */
@Api(value = "/Account", tags = "Account", description = "账号相关接口")
@RequestMapping(value = "/api/account", produces = {APPLICATION_JSON_UTF8_VALUE})
@RestController
public class AccountController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AccountService accountService;

    @Autowired
    private UserService userService;

    @Autowired
    private LoginService loginService;

    @Autowired
    private WechatMiniService wechatMiniService;

    /**
     * 重置密码默认密码
     */
    private static final String RESET_PASSWORD = "123456";

    @ApiOperation(value = "手机号短信登陆或手机号密码登录(app端deviceToken必传)", response = UserProfileDto.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = UserProfileDto.class)})
    @RequestMapping(method = RequestMethod.POST, value = "/{tenantId}/login")
    public BaseResponse login(HttpServletRequest request,
                              @PathVariable @ApiParam(value = "应用ID") String tenantId,
                              @RequestBody @ApiParam(value = "登录信息") LoginParams params) {
        logger.debug(">> login");
        return BaseResponse.buildSuccessResponse(accountService.login(request, tenantId, params));
    }

    @TokenAuthCheck
    @ApiOperation(value = "微信登录获取跳转URL(app端deviceToken必传)", response = UserProfileDto.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = UserProfileDto.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/gotoAuthUrl")
    public BaseResponse gotoAuthUrl(@PathVariable @ApiParam(value = "应用ID") String tenantId) {
        logger.debug(">> login");
        return BaseResponse.buildSuccessResponse(wechatMiniService.gotoAuthUrl(tenantId));
    }

    @ApiOperation(value = "app和小程序登录，userInfo为app端传递用户信息，wechatMiniApp为小程序端传递用户信息", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = UserProfileDto.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/{tenantId}/miniAppLogin/{type}")
    public BaseResponse loginOrRegister(@PathVariable @ApiParam(value = "应用ID") String tenantId,
                                        @PathVariable @ApiParam(value = "三方登录类型") LoginType type,
                                        @RequestBody @ApiParam(required = true, value = "app端传递登陆保存的用户信息") AppThirdLoginDto appThirdLoginDto) {
        logger.debug(">> loginOrRegister");
        if(type == LoginType.QQ || type == LoginType.WECHAT_OPEN){
            return BaseResponse.buildSuccessResponse(loginService.appThirdLogin(tenantId, type, appThirdLoginDto.getUserInfo()));
        }else if(type == LoginType.WECHAT_MINIAPP){
            try{
                return BaseResponse.buildSuccessResponse(loginService.miniAppLogin(tenantId, appThirdLoginDto.getWechatMiniApp()));
            }catch (OpenmoreException e){
                return BaseResponse.buildFailResponse(400, e.getMessage());
            }
        }
        return BaseResponse.buildFailResponse(400,"登录类型不合法");
    }

    /**
     * 根据openid获得用户信息
     */
    @ApiOperation(value = "三方登陆后根据三方openid获得用户信息，判断是否需要绑定手机号码", response = UserProfileDto.class)
    @ApiResponses(value = {@ApiResponse(code = 400, message = "查询数据失败", response = UserProfileDto.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/userInfo/{openid}")
    public BaseResponse getWxUserInfo(@PathVariable(required = false) @ApiParam(value = "三方登录类型") LoginType type,
                                      @PathVariable @ApiParam(required = true, value = "openid") String openid) {
        logger.debug(">> getWxUserInfo");
        try {
            return BaseResponse.buildSuccessResponse(accountService.getUserProfile(type, openid));
        } catch (OpenmoreException e) {
            return BaseResponse.buildFailResponse(400, e.getMsg());
        } catch (Exception e) {
            logger.error(e.getMessage());
            return BaseResponse.buildFailResponse(400, "查询数据失败");
        }
    }

    @ApiOperation(value = "三方登录绑定手机号码", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = UserProfileDto.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/{tenantId}/phoneBind/{type}/{openid}")
    public BaseResponse phoneBind(@PathVariable @ApiParam(value = "应用ID") String tenantId,
                                  @PathVariable @ApiParam(value = "三方登录类型") LoginType type,
                                  @PathVariable @ApiParam(value = "微信openid") String openid,
                                  @RequestParam(required = false) @ApiParam(value = "需要绑定的手机号") String mobile,
                                  @RequestParam(required = false) @ApiParam(value = "验证码") String captcha) {
        logger.debug(">> phoneBind");
        return BaseResponse.buildSuccessResponse(accountService.phoneBind(tenantId, type, openid, mobile, captcha));
    }

    @TokenAuthCheck
    @ApiOperation(value = "退出登录", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/logout")
    public BaseResponse logout() {
        logger.debug(">> logout");
        accountService.logout();
        return BaseResponse.buildSuccessResponse("成功退出");
    }

    @ApiOperation(value = "获得验证码", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/mobile/{mobile}/captcha")
    public BaseResponse sendCaptcha(@PathVariable @ApiParam(value = "应用ID") String tenantId,
                                    @PathVariable @ApiParam(value = "手机号") String mobile) {
        logger.debug(">> sendCaptcha");

        return BaseResponse.buildSuccessResponse(accountService.sendCaptcha(tenantId, mobile));
    }

    @ApiOperation(value = "校验验证码", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/{tenantId}/verify/{mobile}/{captcha}")
    public BaseResponse verifyCaptcha(@PathVariable @ApiParam(value = "应用ID") String tenantId,
                                      @PathVariable @ApiParam(value = "手机号") String mobile,
                                      @PathVariable @ApiParam(value = "验证码") String captcha) {
        logger.debug(">> verifyCaptcha");
        return BaseResponse.buildSuccessResponse(accountService.verifyCaptcha(tenantId, mobile, captcha));
    }
//
//    @ApiOperation(value = "向登录邮箱对应用户的手机发送验证码", response = String.class)
//    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
//    @RequestMapping(method = RequestMethod.GET, value = "/phoneCaptcha/byLoginWith/{email}")
//    public BaseResponse sendCaptchaByLoginEmail(@PathVariable @ApiParam(value = "登录邮箱") String email) {
//        logger.debug(">> sendCaptchaByLoginEmail");
//        return BaseResponse.buildSuccessResponse(accountService.sendCaptchaByLoginEmail(email));
//    }
//
//    @ApiOperation(value = "校验对应用户手机上的验证码", response = String.class)
//    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
//    @RequestMapping(method = RequestMethod.GET, value = "/verify/{captcha}/byLoginWith/{email}")
//    public BaseResponse securityLoginWith(@PathVariable @ApiParam(value = "登录邮箱") String email,
//                                          @PathVariable @ApiParam(value = "验证码") String captcha) {
//        logger.debug(">> verifyCaptchaByLoginEmail");
//        return BaseResponse.buildSuccessResponse(accountService.securityLoginWith(email, captcha));
//    }

    @TokenAuthCheck
    @Transactional
    @ApiOperation(value = "修改密码，需要客户端二次验证新密码是否一致", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/password")
    public BaseResponse changePassword(@RequestParam @ApiParam(value = "新密码") String newPassword,
                                       @RequestParam @ApiParam(value = "旧密码") String oldPassword) {
        logger.debug(">> changePassword");
        if (userService.validatePassword(MyThreadLocalConfig.getUser(), oldPassword)) {
            userService.changePassword(MyThreadLocalConfig.getUser(), newPassword);
        } else {
            throw new OpenmoreException("旧密码不正确");
        }
        return BaseResponse.buildSuccessResponse("修改成功");
    }

    //@TokenAuthCheck
    @Transactional
    @ApiOperation(value = "重置登录密码,不传参数则重置默认123456", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/{tenantId}/resetPassword")
    public BaseResponse resetPassword(@PathVariable @ApiParam(value = "应用ID") String tenantId,
                                      @RequestParam @ApiParam(value = "用户手机号码", required = true) String phone,
                                      @RequestParam(required = false) @ApiParam()String password) {
        logger.debug(">> resetPassword");
        if(StringUtils.isEmpty(phone)){
            return BaseResponse.buildFailResponse(400, "手机号码不能为空");
        }
        if(StringUtils.isEmpty(password)){
            password = RESET_PASSWORD;
        }
        if(password.length()<6){
            return BaseResponse.buildFailResponse(400, "密码长度小于6位");
        }
        User user = userService.getUserByPhone(tenantId, phone);
        if(null == user){
            return BaseResponse.buildFailResponse(400, "手机号用户不存在");
        }
        userService.changePassword(user, password);
        return BaseResponse.buildSuccessResponse("重置成功");
    }
    @TokenAuthCheck
    @Transactional
    @ApiOperation(value = "设置初始登录密码", response = String.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/setPassword")
    public BaseResponse setPassword(@RequestParam() @ApiParam(name = "密码", required = true) String password) {
        logger.debug(">> setPassword");
        userService.setPassword(MyThreadLocalConfig.getUser(), password);
        return BaseResponse.buildSuccessResponse("密码设置成功");
    }

    @ApiOperation(value = "获得图片验证码，图片流")
    @ApiResponses(value = {
            @ApiResponse(code = 4000, message = "请求失败：验证码已经失效，请重试！", response = BaseResponse.class),
            @ApiResponse(code = 4000, message = "请求失败：验证码不正确！", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/imgCaptcha/w/{width}/h/{height}")
    public void getImgCaptcha(HttpServletRequest request,
                              HttpServletResponse response,
                              @PathVariable @ApiParam(value = "验证码宽度") Integer width,
                              @PathVariable @ApiParam(value = "验证码高度") Integer height) {
        logger.debug(">> getImgCaptcha");
        accountService.getImgCaptcha(request, response, width, height);
    }

    @ApiOperation(value = "校验图片验证码")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "校验成功", response = BaseResponse.class),
            @ApiResponse(code = 4000, message = "验证码不正确！", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/verifyImgCaptcha/{captcha}")
    public BaseResponse verifyImgCaptcha(HttpServletRequest request,
                                         @PathVariable @ApiParam(value = "验证码内容") String captcha) {
        logger.debug(">> verifyImgCaptcha");
        accountService.verifyImgCaptcha(request, captcha);
        return BaseResponse.buildSuccessResponse("校验成功");
    }

    @TokenAuthCheck
    @ApiOperation(value = "获得当前登录用户登录信息，已经登录的用户重新拉取登录用户信息", response = UserProfileDto.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.GET, value = "/loginInfo")
    public BaseResponse getLoginInfo() {
        logger.debug(">> getLoginInfo");
        return BaseResponse.buildSuccessResponse(accountService.getLoginInfo());
    }
    @TokenAuthCheck
    @ApiOperation(value = "换绑手机号", response = BaseResponse.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = BaseResponse.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/changePhone")
    public BaseResponse changePhone(@RequestParam() @ApiParam(required = true, value = "手机号")String phone,
                                    @RequestParam @ApiParam(required = true, value = "验证码") String captcha) {
        logger.debug(">> changePhone");
        User user = MyThreadLocalConfig.getUser();
        userService.changePhone(user.getId(), phone, captcha);
        return BaseResponse.buildSuccessResponse("换绑成功");
    }
    @TokenAuthCheck
    @ApiOperation(value = "已登录用户去绑定微信号", response = UserProfileDto.class)
    @ApiResponses(value = {@ApiResponse(code = 4000, message = "请求失败：原因", response = UserProfileDto.class)})
    @RequestMapping(method = RequestMethod.PUT, value = "/bindWechat")
    public BaseResponse userBindWechat(@RequestParam() @ApiParam(required = true, value = "手机号")String openId,
                                    @RequestParam @ApiParam(required = true, value = "验证码") String nickName) {
        logger.debug(">> userBindWechat");
        User user = MyThreadLocalConfig.getUser();
        return BaseResponse.buildSuccessResponse(userService.userBindWechat(user.getId(), openId, nickName));
    }


}




